package com.weic.easycache.access;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;

import android.annotation.SuppressLint;
import android.net.http.AndroidHttpClient;
import android.os.Build;
import android.util.Log;

@SuppressLint("NewApi")
public class HttpService_v8 extends AbsNetAces {

	public HttpService_v8(boolean jsonAndStatus, boolean gzipEnabled) {
		super(jsonAndStatus, gzipEnabled);
	}

	@Override
	protected HttpConnResp execAccess(String url, int method, Map<String, String> headers,
			List<NameValuePair> entityParams) throws UnknownHostException,
			ConnectTimeoutException, SocketTimeoutException, IOException {
		if(LOG) Log.i(LOG_TAG, "[HttpService_v8.execAccess]");
		HttpUriRequest httpRequest = createHttpRequest(url, method, entityParams, getDefaultEncoding());

		Map<String, String> defHeaders = getDefaultHeaders();
		if(defHeaders != null) addHeaders(httpRequest, defHeaders);
		if(headers != null) addHeaders(httpRequest, headers);

		//if(loadfile) {}//下载文件还是应该加上超时限制，否则会有某些线程无法结束
		HttpParams httpParams = httpRequest.getParams();
		int timeoutMs = getTimeoutMs();
		/*Reevaluate this connection timeout based on more wide-scale
        / data collection and possibly different for wifi vs. 3G.*/
		HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
		HttpConnectionParams.setSoTimeout(httpParams, timeoutMs);

		HttpResponse response = getHttpClient().execute(httpRequest);
		return new HttpConnResp(response, null);
	}

	protected static HttpUriRequest createHttpRequest(String url, int method,
			List<NameValuePair> entityParams, String encoding) throws UnsupportedEncodingException {
		switch(method) {
		case Method.DEPRECATED_GET_OR_POST:
			if (entityParams != null) {
				HttpPost request = new HttpPost(url);
				setBodyEntity(request, entityParams, encoding);
				return request;
			} else {
				return new HttpGet(url);
			}
		case Method.POST:
			HttpPost httpPost = new HttpPost(url);
			setBodyEntity(httpPost, entityParams, encoding);
			return httpPost;
		case Method.PUT:
			HttpPut httpPut = new HttpPut(url);
			setBodyEntity(httpPut, entityParams, encoding);
			return httpPut;
		case Method.GET:
			return new HttpGet(url);
		case Method.DELETE:
			return new HttpDelete(url);
		}
		return null;
	}

	protected static void addHeaders(HttpUriRequest httpRequest, Map<String, String> headers) {
		for (String key : headers.keySet()) {
			httpRequest.setHeader(key, headers.get(key));
		}
	}

	protected static void setBodyEntity(HttpEntityEnclosingRequestBase request,
			List<NameValuePair> entityParams, String encoding) throws UnsupportedEncodingException {
		request.addHeader(HTTP.CONTENT_TYPE, getBodyContentType());
		if(entityParams != null) request.setEntity(new UrlEncodedFormEntity(entityParams, encoding));
	}

	private HttpClient mClient;
	private HttpClient getHttpClient() {
		if(mClient == null) {
			//if(Build.VERSION.SDK_INT >= 9);	//将不走本类的Case，基于HttpURLConnection
			if(Build.VERSION.SDK_INT >= 8) {
				mClient = AndroidHttpClient.newInstance(getUserAgent());
			}else {
				mClient = new DefaultHttpClient();
			}
		}
		return mClient;
	}
}
